// pushing-boxes_test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <string.h>
#include<Windows.h>
#include<Mmsystem.h>
#pragma comment(lib,"winmm.lib")
using namespace std;

//宏定义数据
#define X 10	//行数
#define Y 13	//列数
#define LEVEL1_X 3	//第一关人物初始横坐标
#define LEVEL1_Y 4	//第一关人物初始纵坐标
#define LEVEL2_X 2	//第二关人物初始横坐标
#define LEVEL2_Y 11	//第二关人物初始纵坐标
#define SPACE 0	//空地
#define WALL 1	//墙
#define BOX 2	//箱子
#define DEST 3  //目的地
#define PLAYER 4//玩家

//可以用getchar来移动吗
/*
	推箱子:
		菜单界面:
			展示选项: 开始游戏 设置 教程 退出
			用户输入1——开始,2——设置,3——教程，4——退出
			回车确认选项
				进入游戏: 进入游戏界面
				设置: 设置界面
				教程: 教程界面
				退出: 结束游戏
		设置界面:
			展示选项: 音效 音乐 返回主页面
			用户：音效需要easyx,调用mouse左键
			单击选项
				音效——开关
				音乐——开关
				返回主页面：主页面
		教程页面：
			展示选项: 教程文档 返回主页面
			用户输入1——返回主页面
			会车确认选项
				返回主页面——主页面


		游戏界面:
			展示地图: 展示小人 地图
			用户wasd移动
				移动后:
					小人进入空地：移动一格
					推动箱子：人和箱子移动一格，箱子进入另一个空地or进入目的地
					撞墙，无法移动：画面不变化
		暂停界面:
			展示选项: 继续游戏 返回主页面 退出 计时器
			用户输入1——继续,2—主页面，3-退出
			回车确认选项
				继续游戏: 进入游戏界面
				主页面：返回主页面
				退出: 结束游戏

		结束界面:
			展示选项: 继续游戏 退出
			用户输入1——继续,2——退出
			回车确认选项
				继续游戏: 进入下一关游戏界面
				退出: 结束游戏

*/
/*
//-----------------数据设计------------------
			/*
				0表示空地
				1表示墙
				2表示箱子
				3表示目的地
				4表示人物

				map[3][5] = 2// 坐标(3,5)是箱子
			*/

int map[2][X][Y];  //初始化地图
int level = 1;	   //当前所在关
int CHARATER_X, CHARATER_Y;  //人物当前的x，y坐标，移动后就要修改

//-----------------数据设计------------------


   //---------------view-------------------
/*
	负责人: WL
	功能:
		while(1)}{
			1. 展示界面
			2. 接收玩家输入
				键盘输入1,2,3,4+回车 执行对应选项
					进入游戏: 进入游戏界面
					设置: 设置界面
					教程: 教程界面
					退出: 结束游戏
		}
	参数: void
	返回值: void
*/
void setPrintColor(int color);
void gotoXY(int x, int y);
void clear(int x, int y, int w, int h);
void menuView();

/*
	负责人: WL
	功能:
		while(1)}{
			1. 展示界面  音效 音乐 返回主页面
			2. 接收玩家输入
			用户：音效需要easyx,调用mouse左键
			键盘输入1,2,3+回车 执行对应选项
			单击选项
				1：敬请期待
				2：敬请期待
				3：主页面
	参数: void
	返回值: void
*/
void setView();
void timer();

/*
	负责人: QD
	功能:
		while(1)}{
			1. 展示界面  教程文档 返回主页面
			2. 接收玩家输入
			键盘输入1+回车 执行对应选项
				 1：返回主页面
	参数: void
	返回值: void
*/
void teachView();
/*
负责人:QD
功能:
	while(1)}{
		1. 展示界面
		2. 接收玩家输入
			键盘输入1,2,3,回车 执行对应选项
				继续游戏: 进入游戏界面
			主页面：返回主页面
			退出: 结束游戏
	}
参数: void
返回值: void
*/
void temperView();

/*
	负责人: JY
	功能:
		while(1)}{
			1. 展示界面  继续游戏 退出
			2. 接收玩家输入
				键盘输入1,2+回车 执行对应选项
					1：下一关页面（如果没有了：敬请期待）
					2：退出

		}
	参数: void
	返回值: void
*/
void gameoverView();
/*
	负责人: YB
	功能:
		1. 初始化游戏数据: 小人, 地图(墙,空地，箱子，目的地) service提供初始化函数
		while(1){
			2. 打印/绘制界面: 小人, 地图	view
			3. 判断用户有没有输入{ view
				如果有:                                                            ？？？？
					判断用户输入的类型  view
						方向: 修改方向:     service提供修改方向函数

						空格: 暂停游戏: 展示暂停界面
			}
			4. 移动{                                                               ？？？？
				判断:
					判断小人 前面的位置 是什么东西   service提供判断函数 判断移动后的情况
					可能是墙,空地,箱子

				执行:
					如果是墙: 不能移动，无变化
					如果是空地：移动	  service提供修改函数  修改移动后的数据情况
					如果是箱子: 判断   service提供修改函数
							箱子前面是墙：不移动
							箱子前面是空地：小人和箱子正常移动一格		service提供判断函数 判断移动后的情况
			}
			5.判断是否推箱子入目的地{
				退入目的地：复位数加一
			}
			6.判断是否全部箱子入目的地{
				全部退入目的地：gameoverView
			}
		}
	参数: void
	返回值: void
*/
void gameView();

//---------------view-------------------

//---------------service-------------------

//service提供初始化函数
/*
	负责人: YB
	功能:
		地图 小人位置
		地图:
			地图中间初始化为空地(0)
			地图周围一圈墙(1)
			地图中间初始化为箱子(2)
			地图中间初始化为目的地(3)
			地图中间初始化为人物(4)


		人位置:
			地图下方左边
			朝右走
		人方向: d

	参数: void
	返回值: void

*/
void init(void);


//service提供修改方向函数
/*
	注意: service不接收输入 不打印界面

	负责人:XQ
	功能:
		1. 判断用户输入的方向 和人的方向  是否重合
			如果重合: 返回0
		2. 人的方向 = 用户输入方向
			返回1
	参数:
		userInput: 用户输入的方向
	返回值:
		0表示方向修改失败
		1表示方向修改成功
*/
int updateDir(char userInput);


//service提供判断函数 判断小人前面是什么
	/*
		负责人:XQ
		功能:
			1. 根据小人坐标 和人下一步的方向  获取人头前一格的坐标
			2. 判断 地图中 这个坐标是什么内容
				如果是墙: 返回0
				如果是空地: 返回1

			3. (如果是箱子)
				判断 ：箱子前面是什么内容
				如果是墙或者箱子: 返回0
				如果是空地: 返回1

		参数: void
		返回值:
			0表示前面是墙or箱子前面是墙或箱子
			1表示前面是空地and箱子前面是空地

	*/
int forward(char userinput);


//service提供修改函数 小人移动后的数据情况
	/*
		负责人:JR
		功能:
			1. 判断是推动箱子的情况 还是空地的情况
			2.如果是空地:
				人移动一格
			3.如果是箱子:
				判断：箱子进入空地or目的地
				1. 空地：人和箱子移动一格
				2. 目的地：人和箱子移动一格，并且复位数+1

		参数:
			result:
				1 表示可以移动
		返回值: void

	*/
void move(int result);

//service提供判断函数 箱子推入目的地后数据情况

	/*
		负责人:JR
		功能:
			1. 根据复位箱子数目，判断是否通过

		参数: void
		返回值:
			0表示没有通过
			1表示通过：打印结束游戏界面

	*/
int allright();
//---------------service-------------------


int main()
{
	cout << "Hello World!" << endl;
}


void setPrintColor(int color) {
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}
void gotoXY(int x, int y)
{
	COORD c;
	c.X = x - 1;
	c.Y = y - 1;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
}
void clear(int x, int y, int w, int h)
{
	for (int i = 0; i < h; i++) {
		gotoXY(x, y + i);
		for (int j = 0; j < w; j++) putchar(' ');
	}
}
void menuView() 
{
	setPrintColor(0xf2);
	gotoXY(63, 3);
	printf("推  箱  子");
		int userChoose = 0;
		while (1) {		
			if (userChoose == 0) setPrintColor(0x6f);
			gotoXY(64, 6);
			printf("开始游戏");
			if (userChoose == 0) setPrintColor(0x8f);
			if (userChoose == 1) setPrintColor(0x6f);
			gotoXY(64, 9);
			printf("进入设置");
			if (userChoose == 1) setPrintColor(0x8f);
			if (userChoose == 2) setPrintColor(0x6f);
			gotoXY(64, 12);
			printf("游戏教程");
			if (userChoose == 2) setPrintColor(0x8f);
			if (userChoose == 3) setPrintColor(0x6f);
			gotoXY(64, 15);
			printf("退出游戏");
			if (userChoose == 3) setPrintColor(0x8f);
			char input = _getch();
			switch (input) {
			case 'w':
				userChoose -= 1;
				if (userChoose == -1) userChoose = 3;
				break;
			case 's':
				userChoose = (userChoose + 1) % 4;
				break;
			case '\r':
				clear(3, 2, 80, 20);
				switch (userChoose) {
				case 0:
					gameView();
					break;
				case 1:
					setView();
					break;
				case 2:
					teachView();
					break;
				case 3:
					exit(0);
					break;
				}
				clear(3, 2, 36, 20);
				break;
			}
		}
}


void setView() 
{
	setPrintColor(0xf2);
	gotoXY(62, 3);
	printf("设 置 界 面");
	int userChoose = 0;
	while (1) {
		if (userChoose == 0) setPrintColor(0x6f);
		gotoXY(64, 6);
		printf("开启音乐");
		if (userChoose == 0) setPrintColor(0x8f);
		if (userChoose == 1) setPrintColor(0x6f);
		gotoXY(64, 9);
		printf("开启音效");
		if (userChoose == 1) setPrintColor(0x8f);
		if (userChoose == 2) setPrintColor(0x6f);
		gotoXY(63, 12);
		printf("返回主页面");
		if (userChoose == 2) setPrintColor(0x8f);
		char input = _getch();
		switch (input) {
		case 'w':
			userChoose -= 1;
			if (userChoose == -1) userChoose = 3;
			break;
		case 's':
			userChoose = (userChoose + 1) % 4;
			break;
		case '\r':
			clear(3, 2, 80, 20);
			switch (userChoose) {
			case 0:
				mciSendString("open kk.mp3 alias music", 0, 0, 0);
				mciSendString("play music repeat", 0, 0, 0);
				break;
			case 1:
				mciSendString("open kk.mp3 alias music", 0, 0, 0);
				mciSendString("play music repeat", 0, 0, 0);
				break;
			case 2:
				menuView();
				break;
			}
			clear(3, 2, 36, 20);
			break;
		}
	}
}

void timer()
{
	int i, j;
	for (i = 0; i < 100; i++)
		for (j = 0; j < 60; j++)
		{
			Sleep(1000);
			gotoXY(80, 2);
			setPrintColor(0xe4);
			printf("\b\b\b\b\b%d%d:%d%d", i / 10, i % 10, j / 10, j % 10);
		}
}

void teachView() 
{
	setPrintColor(0xf2);
	gotoXY(40, 3);
	printf("推 箱 子 游 戏 教 程\n");
	setPrintColor(0xf);
	gotoXY(15, 5);
	printf("    《推箱子》是一款休闲益智类游戏，1982 年由日本Thinking Rabbit \n\
		   公司在安卓平台 发布。该游戏的目的就是用最少的步数把一个拥挤\n\
	           的仓库中的所有箱子都推到目标位置上,将立方体移动到相应的目标， \n\
		   有时方向必须恰到好处，有时几个立方体会同时移动，一次只能推动\n\
		   一个箱子，游戏包含2个关卡，w - 向上移动；s - 向下移动；a - 向左\n\
		   移动；d - 向右移动。\n\n\n\n\n\n");
	setPrintColor(0xf2);
	gotoXY(3, 2);
	printf("返回主界面\n\n");
	setPrintColor(0xf);
	printf("(按q返回主界面)\n");
	char a = getchar();
	if (a == 'q') menuView();
}


void temperView() 
{
	setPrintColor(0xf2);
	gotoXY(62, 3);
	printf("暂 停 界 面");
	int userChoose = 0;
	while (1) {
		if (userChoose == 0) setPrintColor(0x6f);
		gotoXY(64, 6);
		printf("返回游戏");
		if (userChoose == 0) setPrintColor(0x8f);
		if (userChoose == 1) setPrintColor(0x6f);
		gotoXY(64, 9);
		printf("返回主界面");
		if (userChoose == 1) setPrintColor(0x8f);
		if (userChoose == 2) setPrintColor(0x6f);
		gotoXY(63, 12);
		printf("退出游戏");
		if (userChoose == 2) setPrintColor(0x8f);
		char input = _getch();
		switch (input) {
		case 'w':
			userChoose -= 1;
			if (userChoose == -1) userChoose = 3;
			break;
		case 's':
			userChoose = (userChoose + 1) % 4;
			break;
		case '\r':
			clear(3, 2, 80, 20);
			switch (userChoose) {
			case 0:
				gameView();
				break;
			case 1:
				menuView();
				break;
			case 2:
				exit(0);
				break;
			}
			clear(3, 2, 36, 20);
			break;
		}
}


void gameoverView()
{

}


void gameView() 
{

}


void init(void) 
{
	//临时数组
	int temp[2][X][Y] =
	{
		{
			{0,0,0,0,0,0,0,0,0,0,0,0,0},
			{0,0,0,1,1,1,1,0,0,0,0,0,0},
			{0,0,0,1,0,0,1,1,0,0,0,0,0},
			{0,0,0,1,4,3,0,1,0,0,0,0,0},
			{0,0,0,1,3,3,2,1,1,0,0,0,0},
			{0,0,0,1,0,2,2,0,1,0,0,0,0},
			{0,0,0,1,0,0,0,0,1,0,0,0,0},
			{0,0,0,1,1,1,1,1,1,0,0,0,0},
			{0,0,0,0,0,0,0,0,0,0,0,0,0},
			{0,0,0,0,0,0,0,0,0,0,0,0,0}
		},
		{
			{0,0,0,0,1,1,1,1,0,0,0,0,0},
			{1,1,1,1,1,0,0,1,1,1,1,1,1},
			{1,0,2,0,0,2,0,0,0,0,2,4,1},
			{1,0,1,0,1,0,2,0,1,1,1,2,1},
			{1,0,0,0,2,0,1,0,0,1,0,0,1},
			{1,1,1,0,1,0,0,0,0,1,2,0,1},
			{0,1,0,0,0,1,2,1,0,2,0,0,1},
			{0,1,0,3,3,3,3,3,3,3,3,3,1},
			{0,1,0,0,0,1,1,1,1,1,1,1,1},
			{0,1,1,1,1,1,0,0,0,0,0,0,0}
		}
	};
	memcpy(map, temp, sizeof(temp));
}


int updateDir(char userInput) 
{


}


int forward(char userinput) 
{

}


void move(int result) 
{

}


int allright() 
{

}




// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
